package org.example;

import org.example.entity.Course;
import org.example.entity.Student;
import org.example.message.CourseCheckMessage;
import org.example.message.CourseOperateMessage;
import org.example.message.StudentOperateMessage;
import org.example.message.StudentCheckMessage;

import java.util.*;
import java.util.stream.Collectors;

public class StudentManager {

    public static final HashMap<String, Set<String>> ELECTIVES_MAP = new HashMap<String, Set<String>>();

    public static final HashMap<String, Student> STUDENT_HASHMAP = new HashMap<String, Student>();

    public static final HashMap<String, Course> COURSE_HASHMAP = new HashMap<String, Course>();


    public StudentManager() {
    }

    /**
     * TODO 添加学生信息
     * 1、先查询STUDENT_HASHMAP中的key中是否存在要添加学生的学号
     * 2、存在则提示添加失败
     * 3、不存在则将学号和学生对象添加到STUDENT_HASHMAP中
     */
    public void addStudent(Student student) {
        String studentId = student.getStudentId();
        if (STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentAddFailed();
            return;
        }
        STUDENT_HASHMAP.put(studentId, student);
        StudentOperateMessage.studentAddSuccess();
    }

    /**
     * TODO 删除学生信息
     * 1、先查询STUDENT_HASHMAP中的key中是否存在要删除学生的学号
     * 2、不存在则提示学生不存在
     * 3、存在则删除学生信息
     */
    public void deleteStudent(String studentId) {
        if (!STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentNoExist();
            return;
        }
        STUDENT_HASHMAP.remove(studentId);
        StudentOperateMessage.studentDeleteSuccess();
    }

    /**
     * TODO 更新学生信息
     * 使用HashMap的put方法覆盖，无则添加，有则覆盖
     */
    public void updateStudent(Student student) {
        String studentId = student.getStudentId();
        STUDENT_HASHMAP.put(studentId, student);
        StudentOperateMessage.studentUpdateSuccess();
    }

    /**
     * TODO 通过id查询学生信息
     * 1、先查询STUDENT_HASHMAP中是否已存在要查询学生的学号
     * 2、不存在new对象返回
     * 3、存在返回对应学生信息
     */
    public Student selectStudentById(String studentId) {
        if (!STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentSelectFailed();
            return new Student();
        }
        StudentOperateMessage.studentSelectSuccess();
        return STUDENT_HASHMAP.get(studentId);
    }

    /**
     * TODO 通过name查询学生信息
     * 1、使用stream流筛选出所有学生姓名为studentName的集合studentSelectList
     * 3、studentSelectList为空则返回new ArrayList<Student>
     * 4、不为空则返回studentSelectList
     */
    public List<Student> selectStudentByName(String studentName) {
        List<Student> selectStudentByNameList = STUDENT_HASHMAP.values().stream()
                .filter(student -> student.getStudentName().equals(studentName))
                .collect(Collectors.toList());
        if (selectStudentByNameList.isEmpty()) {
            StudentOperateMessage.studentSelectFailed();
            return new ArrayList<Student>();
        }
        StudentOperateMessage.studentSelectSuccess();
        return selectStudentByNameList;
    }

    /**
     * TODO 添加课程信息
     * 1、先查询COURSE_HASHMAP中是否已存在要添加课程的课程编号
     * 2、存在则提示添加失败
     * 3、不存在则添加到COURSE_HASHMAP
     */
    public void addCourse(Course course) {
        String courseId = course.getCourseId();
        if (COURSE_HASHMAP.containsKey(courseId)) {
            CourseOperateMessage.courseAddFailed();
            return;
        }
        COURSE_HASHMAP.put(courseId, course);
        CourseOperateMessage.courseAddSuccess();
    }

    /**
     * 将选课从学生类中去除
     * 1、从数据库设计上，选课属于学生和课程之间的联系
     * 2、在进行选课的时候要先在set集合中查询学号和课程号是否存在
     * 如果存在再遍历学生List找到该学生，再将课程号添加到学生选课集合中
     * 3、如果使用Map存学生选课信息，可以直接通过键值得到学生选课集合进行操作
     * 不再遍历学生List
     */

    //TODO 学生选课
    public void studentSelectCourse(String studentId, String courseId) {
        //1、查询进行选课的学生是否存在
        if (!STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentNoExist();
            return;
        }
        //2、查询进行选课的课程是否存在
        if (!COURSE_HASHMAP.containsKey(courseId)) {
            CourseOperateMessage.courseNoExist();
            return;
        }
        Set<String> electives = ELECTIVES_MAP.computeIfAbsent(studentId, k -> new HashSet<String>());
        if (electives.add(courseId)) {
            CourseOperateMessage.selectCourseSuccess();
            return;
        }
        CourseOperateMessage.selectCourseFailed();
    }

    /**
     * TODO 学生退课
     */
    public void studentDropCourse(String studentId, String courseId) {
        //1、查询进行选课的学生是否存在
        if (!STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentNoExist();
            return;
        }
        //2、查询进行选课的课程是否存在
        if (!COURSE_HASHMAP.containsKey(courseId)) {
            CourseOperateMessage.courseNoExist();
            return;
        }
        ELECTIVES_MAP.computeIfPresent(studentId, (k, electives) -> {
            if (!electives.isEmpty() && electives.contains(courseId)) {
                electives.remove(courseId);
                CourseOperateMessage.dropCourseSuccess();
                return electives.isEmpty() ? null : electives;
            }
            CourseOperateMessage.dropCourseFailed();
            return electives;
        });
    }

    /**
     * TODO 查询学生选课
     * 1、查询要查询学生选课信息的学生学号是否存在
     * 2、不存在提示该学生不存在
     * 3、存在则返回学生的选课列表
     */
    public List<String> selectElectives(String studentId) {
        if (!STUDENT_HASHMAP.containsKey(studentId)) {
            StudentOperateMessage.studentNoExist();
            return new ArrayList<>();
        }
        if (!ELECTIVES_MAP.containsKey(studentId)) {
            StudentOperateMessage.studentElectiveNone();
            return new ArrayList<>();
        }
        return new ArrayList<>(ELECTIVES_MAP.get(studentId));
    }

    // TODO 打印信息
    public <T> void printAllInformation(HashMap<String, T> map) {
        map.forEach((s, t) -> System.out.println(s + ":" + t));
    }
}
